package com.maxdu.labs.stt.activities;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.util.ArrayList;
import java.util.List;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import com.example.stt.R;
import com.facebook.Request;
import com.facebook.Request.GraphUserListCallback;
import com.facebook.Response;
import com.facebook.Session;
import com.facebook.SessionState;
import com.facebook.UiLifecycleHelper;
import com.facebook.model.GraphUser;
import com.facebook.widget.ProfilePictureView;
import com.maxdu.labs.stt.constants.Constants;
import com.maxdu.labs.stt.models.db.UserVSTPlanDBHelper;
import com.parse.ParseException;
import com.parse.ParseObject;
import com.parse.SaveCallback;

public class InviteFriendsToTPlanActivity extends Activity {

	private ListView friendsLV;
	private List<String> people = null;
	private FriendsAdapter adapter;
	private List<GraphUser> allFriends;
	private String trainingId = null;
	
	private UiLifecycleHelper uiHelper;
	private Session.StatusCallback callback = new Session.StatusCallback() {
	    @Override
	    public void call(final Session session, final SessionState state, final Exception exception) {
	        onSessionStateChange(session, state, exception);
	    }
	};
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		
		setContentView(R.layout.activity_invite_friends_to_training);
		
		friendsLV = (ListView)findViewById(R.id.list_friends);
		allFriends = new ArrayList<GraphUser>();
		adapter = new FriendsAdapter(getApplicationContext(), R.layout.row_invite_friends, allFriends);
		friendsLV.setAdapter(adapter);
		
	    uiHelper = new UiLifecycleHelper(this, callback);
	    uiHelper.onCreate(savedInstanceState);
		
        Intent intent = getIntent();
        Bundle bundle = intent.getExtras();

        if(bundle!=null)
        {
        	//no bundle means no trainingId so this Activity can't work
        	if (bundle.get("trainingId") != null){
	        	
        		trainingId = (String)bundle.getString("trainingId");
        		
	        	if(bundle.get("people") != null){
	        		byte [] peopleByte = bundle.getByteArray("people");
	        		people = restoreByteArray(peopleByte);
	        	}
	        	
		        getMyFriends();
        	}else{
        		Log.e(Constants.LOG_TAG,"InviteFriendsToTPlanActivity::onCreate:: trainingId is NULL (not in the bundle)");
        	}
        }else{
        	Log.e(Constants.LOG_TAG,"InviteFriendsToTPlanActivity::onCreate:: bundle is NULL so we don't know the trainingId");
        }
	}
	
	private void getMyFriends(){
	    Session activeSession = Session.getActiveSession();
	    if(activeSession.getState().isOpened()){
	        Request friendRequest = Request.newMyFriendsRequest(activeSession, 
	            new GraphUserListCallback(){
	                @Override
	                public void onCompleted(List<GraphUser> users,
	                        Response response) {

	                if (users != null){
	                	if (users.size() > 0){
		                	for (GraphUser user : users){
		                		allFriends.add(user);
		                	}
		                	Log.d(Constants.LOG_TAG,"getMyFriends::users.size() == "+ users.size());
		                	
		                	adapter.notifyDataSetChanged();
	                	}else{
	                		Log.d(Constants.LOG_TAG,"getMyFriends :: users is EMPTY");
	                	}
	                }else{
	                	Log.w(Constants.LOG_TAG, "WARNING :: getMyFriends :: users is NULL" );
	                }
	                    
	            }
	        });
	        Bundle params = new Bundle();
	        params.putString("fields", "id, name, picture");
	        friendRequest.setParameters(params);
	        friendRequest.executeAsync();
	    }
	}

	private void onSessionStateChange(final Session session, SessionState state, Exception exception) {
	    if (session != null && session.isOpened()) {
	        // Get the user's data.
	        getMyFriends();
	    }
	}
	
	@SuppressWarnings("unchecked")
	private List<String> restoreByteArray(byte[] bytes) {
	    try {
	        return (List<String>) (new ObjectInputStream
	                                (new ByteArrayInputStream(bytes)))
	                                .readObject();

	    } catch (ClassNotFoundException e) {
	        Log.e(Constants.LOG_TAG, "Unable to deserialize users.", e); 
	    } catch (IOException e) {
	        Log.e(Constants.LOG_TAG, "Unable to deserialize users.", e); 
	    }  
	    return null;
	}
	
	private class FriendsAdapter extends ArrayAdapter<GraphUser>{

		List<GraphUser> _people;
		
		public FriendsAdapter(Context context, int resource,
				List<GraphUser> objects) {
			super(context, resource, objects);
			
			_people = objects;
		}
		
		@Override
	    public View getView(final int position, View convertView, ViewGroup parent) {
	        View view = convertView;
	        if (view == null) {
	        	LayoutInflater inflater = (LayoutInflater)getContext().getSystemService
	        		      (Context.LAYOUT_INFLATER_SERVICE);
	            view = inflater.inflate(R.layout.row_invite_friends, parent,false);
	        }

	        final GraphUser user = _people.get(position);
	        
	        Log.w(Constants.LOG_TAG,"Adaptor::getView:: user.getId() == " + user.getId());
	        
            TextView nameTextV = (TextView) view.findViewById(R.id.friendtoinvite_name);
            final TextView inviteSentTV = (TextView) view.findViewById(R.id.invite_sent);
            ProfilePictureView profilePictureView = (ProfilePictureView)view.findViewById(R.id.friendtoinvite_picture);
            final Button button = (Button) view.findViewById(R.id.btn_invite);
            
            profilePictureView.setProfileId(user.getId());
            nameTextV.setText(user.getName());
            
            if(people.contains(user.getId())){
            	//user is already in the training
            	button.setVisibility(View.GONE);
            }else{
            	//we set the button so you can send an invite
            	button.setOnClickListener(new OnClickListener() {
					@Override
					public void onClick(View v) {
						InviteFriendToTrainingTask task = new InviteFriendToTrainingTask();
						task.execute(user.getId());
						button.setVisibility(View.GONE);
						inviteSentTV.setVisibility(View.VISIBLE);
					}
				});
            }
	        
	        return view;
	    }
	}
	
	private class InviteFriendToTrainingTask extends AsyncTask<String, Void, Void> {

		@Override
	    protected Void doInBackground(String... userIds) {

	    	if (userIds != null){
	    		String userId = userIds[0];
	    		
	    		if (userId != null && trainingId != null){
	    			saveUserVSFriendToCloud(trainingId, userId, 0);
	    		}else if (userId == null){
	    			Log.e(Constants.LOG_TAG,"ERROR :: InviteFriendToTrainingTask :: doInBackground :: userId is NULL");
	    		}else{
	    			Log.e(Constants.LOG_TAG,"ERROR :: InviteFriendToTrainingTask :: doInBackground :: trainingId is NULL");
	    		}
	    		
	    	}
	    	return null;
	    }
	}
	
	//TODO should implement the UserVSTrainingDBHelper
	private void saveUserVSFriendToCloud(final String trainingId, final String userId, int role){
		if(trainingId != null && userId != null){
			ParseObject userVSTrainingParseObject = new ParseObject(UserVSTPlanDBHelper.PARSE_DB_TABLENAME_USERVSTPLAN);
			
			userVSTrainingParseObject.put(UserVSTPlanDBHelper.PARSE_DB_FIELD_TPLANID, trainingId);
			userVSTrainingParseObject.put(UserVSTPlanDBHelper.PARSE_DB_FIELD_USERID, userId);
			userVSTrainingParseObject.put(UserVSTPlanDBHelper.PARSE_DB_FIELD_ROLE, role);
			
			userVSTrainingParseObject.saveInBackground(new SaveCallback() {
				
				@Override
				public void done(ParseException e) {
					if (e == null){
						Log.d(Constants.LOG_TAG, "we successfully updated to Cloud the UserVSTPlan: TPlan [" + trainingId + "] - User [" + userId + "]" );
			      		Toast.makeText(InviteFriendsToTPlanActivity.this, getResources().getString(R.string.friend_invited), Toast.LENGTH_LONG).show();
					}else{
						Log.w(Constants.LOG_TAG, "PROBLEM when trying to save the the UserVSTPlan: TPlan [" + trainingId + "] - User [" + userId + "] to Cloud. errorMessage:: " + e);
					}
					
				}
			});
		}else {
			Log.e(Constants.LOG_TAG, "UserVSTrainingDBHelper::saveToCloud() :: userVSTraining object IS NULL");
		}
	}
	
}
